home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1996 April
/
CHIP 1996 aprilis (CD06).zip
/
CHIP_CD06.ISO
/
hypertxt.arj
/
92
/
CXX.CD
< prev
next >
Wrap
Text File
|
1995-09-12
|
36KB
|
621 lines
@VBjarne Stroustrup: Termékeny úton a C++ felé@N
Egy új szoftver nem csupán technikai ügy, hanem a
felhasználó munkakultúráját is érinti. Bjarne Stroustrup, a
C++ objektumorientált programozási nyelv alkotója tippeket
nyújt az új programozási stílus ""csendes" bevezetésére.
Szeretnénk Önöknek képet adni arról, hogyan lehet a
C++-t produktívan bekapcsolni a munkánkba és felhasználni.
Némiképp azt is szeretném elérni, hogy eloszoljék a C++-t és
általában az objektumorientált programozást körülvevô köd és
misztikum. Az alábbiakban a nyelv leírását, amint az itt
látható, a C++ elsajátítására rendszerint ajánlott mód
követi: elôször egy jobb C, aztán adatabsztrakció, majd
objektumorientált programozás.
A C++-t, mint programozási eszközt a legszélesebb
értelemben vett rendszerprogramozás számára fejlesztettük
ki. Természetesen más célokra is fel lehet használni -- a
koncepció általános és a C++-t nem zárt rendszernek
tervezték.
Ha mindazonáltal valakitôl azt hallják, hogy olyan
nyelvet vagy valami olyan eszközt talált, amely könnyen
megoldja az Önök összes problémáját, akkor ne higgyék el
neki. Nincsenek csodák, nincs mindenható orvosság. Semmi sem
pótolhatja a gondolkozás kemény munkáját.
A gondokodás annál komolyabb feladatot tûz elénk, minél
jobbak az általunk alkalmazott eszközök. Természetesen
kielégítô, ha oldalakon keresztül assembly kódokat írunk, de
az efféle kielégüléstôl meg van fosztva egy magasabb szintû
nyelv programozója. Most határozottabban kell
elgondolkoznunk azon, hogy tulajdonképpen mit is csinálunk.
Szükségünk van intelligenciára, tapasztalatokra és a
kvalifikált munka legkevésbé mérhetô jellemvonására: az
ízlésre.
Ahhoz, hogy érthetôvé tegyem, mi is a C++, elôször
alapvetô gondolatokat akarok megfogalmazni arról, hogy mi
egy program, és egy nyelvnek mit kellene nyújtania a
programozó számára.
Ha az ember programot ír, akkor a valóság egyfajta
modelljét készíti el. Egy olyan behatárolt modellt, amely
már csak az adott probléma lényegesnek tartott szempontjait
tartalmazza. Azt hiszem, ez az a gondolat, amelynek
megvalósítását az objektumorientált programozás kitûzte maga
elé, és amely körül az egész programozás forog.
A kulcsgondolat a következô: ha probléma van a
programmal, akkor nem a számítástechnika trükktárában
kellene keresgélni, hanem meg kellene próbálni jól
megfigyelni a modellizált tevékenységet, azaz a valóságot,
és aztán alkalmas módot találni a probléma programszinten
való leírására.
Ha ebbôl a látásmódból indul ki az ember, akkor mit
nyújthat egy programozási nyelv erre a célra? Lényegében
segíthet a dolgokat közvetlenül megjeleníteni a programban.
A programozás területén eddig elért legnagyobb
elôrelépés a Fortran bevezetése volt, ami alapjában véve az
aritmetikát tükrözte vissza. Ahelyett, hogy adatokat kellene
fáradságos módon regiszterbe tölteni, majd a regiszterhez
más értékeket hozzáadni és az eredményt egy másik helyen
tárolni, valójában egyszerûen azt írhattuk, hogy @KA = B + C@N.
Ez bizonyos tekintetben minden magasabb szintû
programozási nyelv lényeges jellemvonása. Szeretnénk
továbbra is folytatni ezt az utat.
Ennek egyik elsô példája egy munka John Bentley-tôl és
Brian Kernighan-tôl. Programnyelvet terveztek molekulákkal
foglalkozó emberek számára. Volt egy tankönyvük, amelybôl
megtudták, hogyan néz ki egy molekula, hová illenek be az
atomok, és milyen a térbeli elrendezôdésük. Végeredményben
be lehetett adni egy képletet a tankönyv alapján, és --
csodák csodája -- egy piros-zöld szemüvegen keresztül a
molekulák három dimenzióban láthatóvá váltak a képernyôn.
Mindazonáltal az olyan programnyelvek, amelyek lehetôvé
teszik egy adott alkalmazási terület koncepcióinak
közvetlenül programban való kifejezését, e példájának van
egy súlyos hiányossága: nem használható fel általánosan. E
technika csak a fizikai kémia egy speciális részterületén
mûködik. És minden speciális esetben is csak akkor mûködik,
ha olyan emberekhez fordulhatunk, mint Bentley és Kernighan.
Rendszerint nem ez a helyzet, és még ha így is lenne,
valószínûleg akkor sem lehetne hosszabb távon ilyen
embereket alkalmazni.
@VKözvetlen kifejezések@N
Ezért ugyanezzel a gondolattal foglalkozom, de úgy, hogy
megfizethetô legyen -- részben azáltal, hogy általános
eszközöket bocsájtunk rendelkezésre a koncepciók közvetlen
leképezésére, részben azáltal, hogy a C++-t a szokásos
gépeken elôforduló általános problémák megoldására
fejlesztettük ki. Ugyanis vannak olyan problémák, amelyek
esetében a következô kompromisszumot lehet kötni: szerzünk
egy olyan programozási rendszert, amely megkönnyíti a dolgok
közvetlen formában való kifejezését, de ennek során az
irányítási munkák felemésztik a CPU teljesítményének 90--95
százalékát. Az efféle kompromisszumot elfogadhatatlannak
tartom.
Vizsgáljuk meg alaposabban a C++-hoz vezetô utat.
Elôször elkezdjük a C++-t többé-kevésbé tökéletesebb C-ként
alkalmazni. Könnyen kitûnik, hogy egy C++ program futását a
C és a C++ közös részhalmazán belül csekély mértékben lehet
meggyorsítani egy C programhoz képest. Ennek oka a típusok
szigorúbb ellenôrzése a függvények meghívásakor. Ez nem
jelenti azt, hogy bármely speciális compiler valóban
gyorsabban fut. Azonban azt igen, hogy a C++-ban nincs
szisztematikus overhead. A C++ 99,9%-ig kompatibilis a
C-vel. Száz százalékig sosem lehetne, mert az ellentmondana
a típusellenôrzés alapelvének. A C++ nagymértékben függ a
típusok állandó ellenôrzésétôl. Ez az oka a kisebb
inkompatibilitásoknak. De ahhoz afféle ""nyelvtudósnak"
kellene lenni, hogy megtaláljuk azokat.
A ""tökéletesebb C" elônyei közé tartozik elsôsorban a
típusellenôrzés -- ez lehetôvé teszi a munka idôben való
elkészítését, s ugyanakkor újat tanul az ember.
Az emberek többnyire gyorsan hozzáláttak új
adattípusokat tervezni -- néhány alkalmazásspecifikus
típust. Elvileg ekkor az adatabsztrakció látásmódját
használják, ami nem különösebben bonyolult. Egy új adattípus
koncepcionálisan beleillik a beépített adattípusokról
alkotott megszokott gondolkodásmódba. Ezenkívül az ember
learatja a C++ összes paradigmájának minden elônyét, mivel a
könyvtárak profitálnak abból, hogy az önállóan definiált
adattípusokat a programozó beépített adattípusokként
használhatja anélkül, hogy meg kellene értenie az
implementáció specifikus részleteit.
A C++ betanulásának elsô féléve során elvben a
következôket ajánljuk: az embernek fel kellene hagynia az
objektumorientált programozással, a kategóriák egymás fölé
rendelésével és a típusfák készítésével. Elôször hozzá
kellene szoknia a szigorúbb típushasználathoz és az
adatabsztrakcióhoz. Mindenkit hagyni kellene a saját tempója
szerint tanulni.
Minden átálló sikeres volt, aki követte e tanácsot.
Azaz, ha az embernek egy fél évvel késôbb van leadási
határideje, akkor a javasolt módon ennek ellenére áttérhet a
C++-ra, és még elônyöket is szerezhet abból a következô
feladathoz.
@VA fluktuáció költségei@N
Miért kellene tekintettel lenni a dolgozókra? Biztosan
vannak olyan menedzserképzô-iskolák, ahol azt tanítják, hogy
fel kell venni a legolcsóbb programozókat, ki kell facsarni
ôket, majd a feladat végrehajtása után ki lehet ôket dobni.
Mondhatnánk, hogy ez nem tisztességes, ezért nem kellene
ilyet csinálni -- de egy hétpróbás menedzsert ez nem gyôz
meg. Az efféle irányításnak igen nyomós oka van: a pénz.
Azonban ha alkalmazzuk a legolcsóbb programozókat, és
kifárasztjuk ôket, akkor minden hanyagul lesz elvégezve. Az
emberek, amint lehet, új állást keresnek. Természetesen csak
a legjobb programozók mennek el, hiszen ôk kapnak munkát.
îgy jutunk el a fluktuáció költségeihez. Ha nem bánunk
tisztességesen a dolgozókkal, akkor nem fogják idejüket abba
fektetni, hogy új technikákat tanuljanak meg. Nem lesznek
képesek válaszolni az új kihívásokra. Egyáltalán nem is
fogják azokat észrevenni.
Az USA-ban fennáll egy komoly probléma, különösen az
olyan helyeken mint a Szilícium-völgy, ahol a dolgozók
évente vagy még gyakrabban változtatják munkahelyüket: nem
akarnak olyan képességeket elsajátítani, amit nem tudnak
felhasználni következô munkájuk során. Ez a hozzáállás és az
a vezetôi hozzáállás, miszerint ""Használjuk ki a
programozókat amilyen gyorsan csak lehet, mivel úgyis
elmennek", hosszabb távon visszaüt.
Térjünk vissza a programozási nyelvek problémáihoz.
Bizonyára észrevették, hogy egész idô alatt megkíséreltem
párhuzamot vonni a technológiai és a szociológiai problémák
között. A technikai megoldásokat nem egy szociológiai
problémára lehet alkalmazni és viszont. És a szoftverek
fejlesztése magában foglalja mind az embereket, mind a
gépeket és a nyelveket. Összességében sajnos hajlamosak
vagyunk arra, hogy elfelejtkezzünk az emberekrôl.
@VHogyan segíti a C++ az adatabsztrakciót?@N
Az adatabsztrakció alapjában véve úgy magyarázható el,
mint egy olyan gondolat, amely a programozás folyamatát két
részre bontja. Elôször tervezünk egy bôvített programozási
nyelvet, amely tartalmazza azokat a típusokat, amelyek
reprezentálják az alkalmazási terület alapkoncepcióit. Aztán
konkretizáljuk a típusokat, és azokkal programozunk. Más
szavakkal: felépítünk egy típusokból álló világot, és abban
programozunk -- ahelyett, hogy egyszerûen nekilátnánk, és a
kódokat bitek és byte-ok formájában beírnánk.
Ha közvetítô elrendezésekkel foglalkozunk, akkor
szeretnénk közvetítô szerkezeteket, vezetékeket,
fôvezetékeket, választási puffereket és hasonló dolgokat.
Alapvetôen azzal kezdjük, hogy megemeljük a nyelv szintjét
azáltal, hogy új típusokat tervezünk.
Ha sikerül a típusvilág megtervezése, akkor a további
programozás minden résztvevô számára kellemes munka lesz.
Ha azonban a felhasználó által definiált adattípusokból
áttekinthetetlen összevisszaságot csinálunk, akkor
kutyaszorítóba kerülünk. Ahogy már mondtam, nincs mindenható
orvosság. Az ember kénytelen használni a fejét.
Amit nem szabad figyelmen kívül hagynunk a
programnyelvek produktivitásáról folytatott vitában, és ami
hosszú távon döntôen meghatározza a produktivitást: az
emberek egy nyelvet használnak. A nyelv bármely kultúra
meghatározó eleme. Nemcsak arról van szó, hogy milyen
tulajdonságokkal bír egy nyelv, hanem arról is szó van, hogy
milyen további eszközök állnak a programozó rendelkezésére,
milyen a programkönyvtárak minôsége, milyen szintûek és
milyen jellegûek a szakfolyóiratok, a tankönyvek, a képzés
és a továbbképzés. És nem utolsósorban: miképp folyik az
információcsere?
Minden nyelv kiépíti a saját kultúráját. Remélem, hogy a
C++ kultúrája vonzó -- hiszen a teljes kultúra fontosabb,
mint a nyelv egyetlen ismertetôjegye. Lényeges, hogy egy
nyelvet hogyan lehet használni a valós világban. Ez erôsen
függ az emberektôl és az általuk létrehozható kultúrától.
A C++ bevezetésében az elsô lépés megtétele és az elsô
félév eltelte után megállapíthatjuk, hogy az emberek
valamennyit megértettek és megtanultak, mégpedig nemcsak a
leírt kódokat, hanem többet: ráhangolódtak a kultúrára.
Elolvastak pár tankönyvet. Szabadidejükben játszadoztak az
objektumorientált programozással -- megértették az elveket.
Ezután az idôszak után, amely alatt elsajátítottuk az
alapokat, merészebbek lehetünk, és elônyökre tehetünk szert
a C++ objektumorientált tulajdonságai révén. Arról a
megfigyelésrôl van szó, hogy a koncepciók nem elszigeteltek,
következésképpen az alkalmazás számára tervezett típusok sem
lehetnek függetlenek egymástól.
A C++ egyik sajátossága, hogy az új nyelv megtanulására
fordított erôfeszítéseinket eloszthatjuk hosszabb idôre, és
egyidejûleg produktívak maradunk. Ez azzal kapcsolatos, hogy
a nyelvek tervezését nem olyasvalaminek tartom, amit tiszta
elvek alapján lehetne csinálni. Ugyan elvekbôl és általános
gondolatokból kell kiindulnunk, de egyidejûleg figyelembe
kell vennünk a tényleges korlátokat, amelyek a
képzettségbôl, a gép teljesítményébôl stb. és elsôsorban a
meglévô tapasztalatokból adódnak.
Az objektumorientált programozás egyik fô --
valószínûleg a legrégebbi -- problémája (a Simula
programozási nyelvet tervezô norvégektôl átvéve): programot
írtak egy város szimulálására, amelyben elemzik a
közlekedést. Olyan tárgyaink vannak, mint teherautó,
gépkocsi, mentôautó, tûzoltóautó stb. Ha egyszerûen csak
egyetlen teherautó-típust, egyetlen autótípust, egyetlen
tûzoltóautó-típust írunk le, akkor sok típust kapunk
struktúra nélkül.
A koncepciót nem ültették közvetlenül át a
programnyelvbe, mivel valami elveszett. Elveszett annak az
általánosítása és absztrakciója, hogy ezek mindannyian
gépjármûvek.
Ezért olyan nyelvi jegyre van szükségünk, amely lehetôvé
teszi, hogy a rokon koncepciókat általános formában
jeleníthessük meg. Ez a gondolat gyakorlatilag spontán
fejlôdött ki abból az elképzelésbôl, hogy az, amit teszünk,
kísérlet arra, hogy a valóság elemzésébôl leszûrt
koncepciókat adattípusokban képezzük le.
Az ehhez szükséges alapvetô elképzelés egy felhasználó
által definiált adattípus: el kell döntenünk, hogy mely
típusokra van szükségünk, és egy teljes mûveletsort kell a
saját kezûleg tervezett típusok rendelkezésére bocsájtani.
Ez az ideális adatabsztrakció. Az effajta programozás
számos problémát megold. Ez magában foglalja az adatok
elrejtését és az eljárásokban (procedúra) való programozást.
Most be fogok mutatni egy példát, amelyben összeomlik ez
az ideál. Aztán elmagyarázom az ezen túllépô
objektumorientált technikákat.
@VTúl az adatabsztrakción@N
Ha kizárólag eljárásokra van szükségünk, akkor
természetesen eljárásokban kell programoznunk; ha kizárólag
modulokra, akkor maradhatunk a moduláris programozásnál és
az adatok elrejtésénél; ha kizárólag független adattípusokra
van szükségünk, akkor elegendô az adatabsztrakció. Amirôl
azonban most beszélni akarok: mikor omlik össze az
adatabsztrakció koncepciója? Mikor van szükségünk további
lehetôségekre, és melyek ezek a lehetôségek?
Az itt fennálló probléma tulajdonképpen régi keletû, és
már le van írva a ""Simula Begin" címû könyvben. A probléma
eredeti változatában plotterekrôl volt szó. Elvben egyfajta
grafikus rendszerrôl van szó, amelyben egy absztrakt formára
mutató pointerre van szükségünk, amit -- a konkrét
helyzettôl függôen -- valamiképp manipulálni lehet.
Tehát nem kell azt mondani: ha a kívánt forma például
egy háromszög, akkor forgasd el úgy, ahogy a háromszögeket
forgatni szokás... Szeretnénk megkímélni magunkat a
részletektôl.
Most nézzünk meg egy olyan megoldást, amit az
adatabsztrakció hagyományos stílusú megoldásának neveznék.
Szükségünk van egy felhasználó által definiált adattípusra,
hogy ábrázolhassuk egy forma koncepcióját. Tudjuk, hogy
minden formának van közepe és színe, és tudjuk azt, hogy
milyen mûveleteket akarunk végezni rajta. Eddig minden
rendben. Azonban a legkülönbözôbb formák léteznek: hogyan
ábrázoljuk ôket? Gondolhatnánk arra, hogy egyetlen
megjelenítést használunk minden forma számára, például egy
pontokból álló láncolatot. Azonban ez nem mûködik túl jól:
valójában hány pontból áll egy kör? A formák esetében --
miként a legtöbb más példában -- nem létezik egyetlen,
kézenfekvô megjelenítés a koncepció összes változata
számára.
Ezért megvalósításához egyfajta union-t, tag-union-t,
variant record-ot, vagy bárminek is nevezzük, használunk fel
@K(olyan adatstruktúrára utal, amely több részbôl áll, s ezek
közt van olyan, amelynek típusa többféle, a program adott
helyein tekinthetjük ilyen típusúnak is, olyan típusúnak is;
továbbiakban: variáns rekord -- a szerk.)@N. Ebben szükségünk
van arra a lehetôségre, hogy leírhassuk, milyen típusok
vannak. Tehát beépítünk egy típusleíró mezôt. Ezután elvben
sokirányú elágazásokból (C-ben: @Kswitch-@N, más nyelvekben
@KCASE-struktúrákból@N) álló egyetlen, hatalmas szerkezetként
leírjuk a típushoz szánt mûveleteket. A kód ezáltal ilyen
parancsokkal lesz tele, mint: rajzolj egy formát -- ha kör,
akkor tedd ezt, ha háromszög, akkor tedd azt stb. A dolog
mûködik. Azonban néhány komoly problémát vet fel.
Képzeljük el, hogy van egy kis grafikus szoftverházam.
Tegyük fel, hogy Ön vásárolt tôlem egy grafikai csomagot. Ön
azt szeretné, hogy a grafikus csomaghoz hozzáfûzzek egy új
formát, mondjuk a cégemblémáját. Én azt mondom: ""Rendben,
adjon nekem 10 ezer márkát, és beillesztem a cégemblémáját a
rendszerbe." Ez ugyanis azt jelenti, hogy minden olyan
függvényt módosítanunk kell, amely függ a típus-mezôtôl.
Ön erre azt mondja: ""Tízezer márka?! Önnek elment az
esze! Ez a módosítás egészen egyszerû feladat". Én erre azt
válaszolom: ""Ez igaz, de megtehetem, hogy nem adom oda a
forráskódot. Az üzletem ugyanis ezen a kiváló és gyors
körrajzoló módszeren alapul. A körök tényleg körök. A
hírnevem forog kockán." Ez a módszer tehát nem mûködik. Ez a
programozási stílus csak akkor funkcionál, ha hozzáférhetô a
forráskód.
A következô probléma: mi van akkor, ha ez a grafikus
rendszer az egyik irányítóközpontban, a központi amerikai
hálózati rendszert irányító vezérlôkonzolban található? Ott
akarok egy-két kisebb változtatást végrehajtani, tehát
odamegyek, és elkérem a forráskódot. Ez nem probléma.
Megcsinálom a változtatást, és megállapítom, hogy nem minden
sikerült jól. ""Oké" -- mondom erre -- ""elvégeztem a
munkám, ellenôrizzék le". A problémát tehát egy
szoftverkönyvtáros-félének kell átadnom. ï így szól: --
""Rendben, el fogjuk végezni az integrálást és a tesztelést.
Három hét múlva meg fogja kapni az eredményeket."
A körülményeskedés oka az, hogy hozzá kellett nyúlnom a
rendszer összes kulcsfüggvényéhez. Itt van ugyan a rajzoló
függvény, de hasonló változtatásokat hajtottam végre a
forgató függvényben és másutt. Ha valóban olyan egyszerû
lett volna a dolog, hogy elég egy sokirányú elágazást
megkeresni, akkor aligha adódott volna probléma. De a
programozók ravasz emberek, a valós kód nem így néz ki. A
programozók néhány helyen bizonyára észrevettek közös
vonásokat a kódon belül. Talán így lehet elôállítani azonos
módon a sokszögek különbözô formáit.
Ahhoz, hogy a rendszerhez hozzáfûzhessek egy új formát,
meg kell értenem a régi kódot. Mivel meg kell értenem, ezért
félre is érthetem. És ha félreérthetem, akkor fennáll az a
veszély, hogy megsértem a meglévô és helyesen mûködô
kódokat. Ezért újra szükségünk van egy teljes integrációs és
regressziós tesztre, ha kritikus kódhoz érünk.
Az egyszerû hozzáfûzési feladat a valóságban igencsak
bonyolulttá és hibaérzékennyé vált.
Tekintsünk vissza, és tûnôdjünk el azon, hogy hol van e
problémák gyökere: hol nem követtük eredeti alapelveinket a
dolgok közvetlen kifejezésére?
Akkor, amikor definiáltuk ezeket a formákat. Ha
alaposabban meggondoljuk, a formáknak valójában nincs
megjelenésük -- semmilyen formát nem tudunk magunkra
rajzolni.
Csak a meghatározott formáknak van implementációja, csak
a meghatározott formákat lehet lerajzolni. Röviden:
elfelejtettünk különbséget tenni egy forma általános
koncepciója és valamilyen meghatározott forma között.
A különbség realizálása érdekében most tehát definiálunk
egy általános formát, és nem építünk bele semmiféle variáns
rekordot és típusleíró mezôt. Ugyanis ez volt az, ami a
nehézségeket okozta.
Egyszerûen azt mondjuk: ""Ez minden, amit tudunk egy
formáról." Kiváltképpen csak azt tudjuk, hogy forgatható,
hogy lerajzolható -- annak ellenére, hogy nem tudjuk,
hogyan. Ezért egyszerûen csak megállapítjuk, hogy ilyen
mûveletet lehet végezni rajta. Csak késôbb kell az
implementációt elkészítenünk -- akkor, amikor már tudjuk,
hogy milyen speciális formáról van szó. îgy definiálhatunk
bármilyen különleges formát. Például mondhatjuk azt, hogy a
kör egy olyan formafajta, amelynek van sugara, és amelyet
így meg így lehet forgatni.
Ezt alaposztálynak nevezzük. Azt mondjuk, hogy a kör a
formából van származtatva, azaz a kör egy formafajta, örökli
a forma összes tulajdonságát, és rendelkezésre bocsájtja a
""rotate" (forgatás) és a ""draw" (rajzolás) mûveletek
önálló változatait. Azt is mondhatjuk, hogy lefedi
alaposztályának virtuális eljárásait.
Az ilyenfajta programozásnak van egy nagyon jó
tulajdonsága: ha a rendszerhez hozzá akarok illeszteni egy
új formát, például a cégemblémát, akkor egyszerûen csak
definiálom a cégemblémát. Aztán csak beillesztem -- a régi
kódokhoz nem nyúlok hozzá. Nem változtatok meg semmilyen
kódot, mint az adatabsztrakció esetében.
Az adatabsztrakció -- programozás sokirányú
elágazásokkal -- körülbelül megfelel egy sebész
orvostudományról alkotott elképzelésének: ""Nem tehetünk
semmit anélkül, hogy elôzetesen felvágtuk volna a páciens
hasát". Lehet, hogy ez jó a sebész erszényének, de az
biztos, hogy nem jó a gyomromnak.
Az objektumorientált programozás sok esetben lehetôvé
teszi a változtatásokat a régi kód megsértése nélkül. Ezt
gyakran túlértékelik. Ugyanis ez nem azt jelenti, hogy sosem
kell módosítani a kódokat. Mégcsak azt sem jelenti, hogy meg
kellene próbálnunk ezt elkerülni. Pusztán azt jelenti, hogy
alkalmas esetben el lehet kerülni.
ùj elképzelést alakítottunk ki a programozásról: az
ember eldönti, hogy milyen osztályt akar, és aztán az
adatabsztrakció esetében szokásos módon definiál egy teljes
mûveletsort. A különbség most a következô: közös vonásokat
keresünk a típuson belül, és ezeket közvetlenül, mint
osztályokat fejezzük ki. Ez koncepciók hierarchiájához és
típusok hierarchiájához vezet, és ahhoz a programozási
stílushoz, amit objektumorientáltnak nevezünk. Talán
intellektusunkkal meg tudjuk érteni, hogy ez mûködik.
Azonban, hogy lássuk, valójában milyen hasznos, ahhoz ki
kell próbálni, és hozzá kell szokni. Sok területen nincs
jelentôs haszon az adatabsztrakció technikáival szemben --
éppúgy, miként az adatabsztrakció sok területen csak kis
hasznot hoz az adatok elrejtéséhez képest. De ha szükség van
rá, akkor valóban ki lehet hozni belôle valami klassz
dolgot.
Az objektumorientált programozás ígéretei, amiket
teljesítünk, a következôk: gyorsabb programfejlesztés,
egyszerû programkezelés és a kódok nagyfokú
újrafelhasználhatósága. Röviden: gyorsabban készíthetünk
jobb programokat. Azonban ehhez csak egy jól átgondolt
osztály-terv alapján juthatunk el -- ne várjanak csodára. A
kód egyszerûbb lesz, könnyebb lesz a kód kezelése, de
lesznek olyan tervek is, amelyek nem mûködnek. Ha azonnali,
90 százalékos vagy még nagyobb hasznot várunk -- ahogy azt
egyesek ígérik -- akkor csalódni fogunk.
A tapasztalatok alapján kiderült, hogy rövid távon a
termelékenységbeli és minôségbeli elônyök elég mérsékeltek.
Csak másfél-két év elteltével lehet érzékelni a fenntartási
költségekre, a hibaszázalékokra és a többi hasonló dolgokra
kifejtett hatásokat.
Vannak, akik egybôl fejest ugranak az újdonságba: már
elsô projektjükben felhasználják az összes új tulajdonságot.
A dolog meglepô módon funkcionál. Ha azonban több dolgozóból
indulunk ki, olyan emberekbôl, akik nem túl biztosak a
dolgukban, akkor nem ez a helyes eljárás. Nem kell
szükségszerûen így tenni.
Egy-másfél évig fog tartani, mire otthon fogjuk érezni
magunkat minden technikában, fogásban. Mindegy, hogyan
kezdünk hozzá, ennyi ideig fog tartani. Emiatt éppolyan jó,
ha fokozatosan fogunk hozzá.
@VFélreértések@N
Most szeretnék állást foglalni egy sor elterjedt
félreértésben.
A C++ nem Smalltalk. Vannak, akik ezt sajnálják. Azonban
ha egy Smalltalk-utánzatot akartam volna tervezni, akkor
sokkal jobbat készítettem volna. A C++ egészen más nyelv
mint a Smalltalk, szigorúan tipizált, a hatékonyságot
célozza meg, és összhangban van a más nyelven írt
programokkal.
Nem hiszem, hogy bármiféle igény van
Smalltalk-utánzatokra. Sajnos ezt sokan félreértik azok
közül, akik folyóiratokba írnak cikkeket, és akik a két
nyelv közül csak az egyikhez vagy egyikhez sem értenek
igazán -- s nagyon összezavarják a dolgokat.
A C++-nak része majdnem a teljes C. Alapvetôen mindent
átvett a C-tôl, amit típusbiztos módon részhalmazként le
lehet írni. De ez nem minden. Ha a C++-t ""tökéletesebb
C"-ként alkalmazzuk, akkor néhány -- de nem túl sok --
elônyre teszünk szert az ANSI szabványú C-vel szemben. Az
ANSI C amúgy is inkább a C++ részhalmaza, mint a K&R-C
fôhalmaza. Ugyanis az ANSI C fontos nyelvi jegyei a C++-ból
származnak: a prototípusokat és a ""const"-ot a C++ adta. Az
a furcsa eset állt elô, hogy egy nyelv az utódjától vett át
tulajdonságokat. Ami az öröklést illeti, az már nem ilyen
egyszerû.
Egy további félreértés abból adódik, hogy a C++-t
elôprocesszornak tartják. A C++ egy nyelv. És mivel olyan
nyelv, amely döntôen függ a fordítás közbeni
típusellenôrzésektôl, a statikus típusrendszerektôl, a
láthatósági szabályoktól és hasonló dolgoktól, ezért nem
implementálhatja olyasmi, amit hagyományos elôprocesszorként
lehetne leírni. Minden C++ fordítóprogramnak (compiler)
többet kell tudnia a programról, mint amennyit egy C
compiler egyáltalán tudhat. Ennek megfelelôen egy C++
compiler bonyolultabb és okosabb mint egy C compiler.
Sok ember összezavartságának az az oka, hogy
összekeverik a koncepciót annak implementációjával. Sokáig a
C++ egyetlen implementációja egy általam írt, általában
@KC-Front@N-nak nevezett compiler volt, amely hordozhatósági
okok miatt C forráskódot állított elô. De mit csinált
valójában ez a compiler? Vett egy C++ programot, darabokra
szedte, és teljes mértékben analizálta. Ezen az alapon képes
volt bármilyen géphez generálni assembly kódot vagy C kódot.
Mivel sok ember sosem látott olyan C++ fordítóprogramot,
amely mást hozott volna létre mint C-t, ezért azt gondolták,
hogy a C++ egy C-elôfeldolgozó (preprocesszor). Ez
elszomorított engem, mert egyáltalán nem szeretem az
egyszerû elôfeldolgozókat.
Egy másik félreértés így szól (természetesen e
félreértések közül néhány kereskedelmi érdekekbôl erôs
támogatást kap): a C++ pusztán kifinomult tulajdonságok
véletlenszerû gyûjteménye. Azt hiszem, érthetôvé tettem
azokat a kereteket, amelyek között mûködôképesek ezek a
tulajdonságok. Azt is hangsúlyoztam, hogy miért álltunk el
egy nagy, mindent átfogó tervtôl. A következôket gondolom:
""Tudjuk, hogyan kell valamit megépíteni. Szeretnénk
megpróbálni, szeretnénk látni, hogy honnan származnak a
valódi problémák. És ha már elegendô tapasztalatot
szereztünk, akkor szeretnénk beépíteni a szükségesnek
értékelt tulajdonságokat."
A C++ egyértelmûen alkalmas arra, hogy támogasson egy
szigorúbban tipizált C-változatot, egy ""tökéletesebb C-t".
Továbbá arra is alkalmas, hogy támogassa az adatabsztrakciót
és az objektumorientált programozást. Természetesen
assemblyben is lehet írni objektumorientált programot. Nem
ez a lényeg. A kérdés az, hogy a nyelv segít-e nekünk ebben,
és nem kell-e rendkívüli erôfeszítéseket és képességeket
felhasználnunk ahhoz, hogy megbirkózzunk a feladattal. Ebben
az értelemben sürgôsen azt tanácsolom, hogy ha
objektumorientáltan akarunk programozni, akkor olyan nyelvet
használjunk, amely támogatja azt.
Véleményem szerint minden lényeges pont a Simulától
származik. A Simulának bizonyos tekintetben két fô
leszármazottja van: a Smalltalk és a C++. A kettô közötti
különbség nagyon fontos a két nyelv megértése és
alkalmazhatósága szempontjából. A Smalltalkot olyan
módszernek szánták, amely feloldja a korlátokat a környezet
és a programnyelv között. Ez az egyik módja annak, hogy a
Simulánál rugalmasabbak legyünk. A Smalltalk ezenkívül sok
ötletet vett át a Lisptôl. Véleményem szerint tehát a
Smalltalknak két elôdje volt: a Lisp és a Simula.
@VA C++ megszületése@N
A C++-nak két szülôje volt: a Simula az
osztály-rendszeré, másrészt a C, amelytôl a
rendszerprogramozói képességet nyerte. Azt hiszem, hogy
érdemes elmagyarázni azt a folyamatot, amely ide vezetett.
A C++ eredete visszanyúlik egy olyan fejlesztésig, amit
doktori címem megszerzése érdekében végeztem Cambridge-ben.
Megosztott rendszerek szimulálásán dolgoztam. Simulában
megírtam egy hálózat szimulációját, felhasználva hálózatban
ide-oda vándorló modulokat és egyebeket. Valóban szép
szimuláció volt, sok örömöm telt benne -- még a
hibakeresésben is. Nagyon megbecsültem a Simulától kapott
segítséget.
Az osztályok és a származtatott osztályok koncepciója
valóban lehetôvé tette számomra azt, hogy a gondolataimat
egyenesen átültessem kódokba. Meglehetôsen könnyen ment
minden. És amikor két hónappal késôbb újra visszatértem a
kódhoz, akkor el tudtam olvasni -- noha nem nagyon volt
ellátva megjegyzésekkel -- általában így szokott lenni, ha
az ember egyedül dolgozik. Tehát úgy vélem, a Simula nélkül
nem találhattam volna ki ezt a szimulációt. A Simula
koncepcionális segítséget adott, és egy szigorúan tipizált
rendszert nyújtott, ami azt jelentette, hogy a hibakeresés
során a gép szúrta ki a hibákat, és nem nekem kellett éjnek
idején megtalálnom azokat.
A Simulának nem volt úgymond önkényes típusrendszere.
Sok évvel ezelôtt, a kezdeti idôkben kipróbáltam a Pascalt,
típusrendszere számomra egyszerûen elviselhetetlen kolonc.
A Simula szigorúbban tipizált mint a Pascal, de ezt
egyáltalán nem éreztem tehernek, mivel a típusellenôrzés
azon koncepció szintjén történik, amelyet saját kezûleg
építünk be osztályok formájában. Már nem egy önkényes
rendszert vizsgál, hanem azon keret szilárdságát, amely
mellett döntöttünk. És ez nagy segítség volt.
Szerencsétlen módon azután falnak rohantam. A szimuláció
elviselhetetlenül lassan futott. Az osztályomon lévô IBM
nagyszámítógép teljes munkaidejét lekötöttem. Nem sokat
tehettem. Az implementáció a cégé volt, a Simula átvitele
egy másik gépre nem volt megvalósítható, mivel természeténél
fogva nem volt hordozható -- egyébként a forráskóddal sem
rendelkeztem. Nem tudtam megszabadulni a nyelvtôl, mivel
nagyon nehéz volt olyan szoftverrel együttmûködni, amely más
nyelven íródott.
A rendszernek valóban szép jellemvonásai voltak, és
akkor is drága volt, ha az ember nem használta. îgy átírtam
a szimulátort BCPL-be, és a hajam felét kitéptem, mire
sikerült az eredménybôl kiszedegetni a hibákat. Másrészt a
BCPL egy új, villámgyors kísérleti gépen futott.
Megkaptam az eredményeimet. Ez volt a gyakorlat
tulajdonképpeni célja -- nem az, hogy írjak egy aranyos kis
szimulátort. Néha elfelejtjük, hogy a programokat egy
meghatározott cél érdekében írjuk, s nem öncélúan. Akkor
megfogadtam, hogy sosem követem el újra ezt a hibát.
Az volt a hibám, hogy elégtelen eszközzel fogtam hozzá
egy nagy és súlyos problémához. Néhány évvel késôbb, amikor
egy hasonló fejlesztést kellett elvégeznem, visszavonultam
és megterveztem a C++-t.
@KAz elôadás szövegét németre fordította és szerkesztette:
Gerhard Ertl@N
@VBjarne Stroustrup@N
Bjarne Stroustrup fejlesztette ki a C++ programozási
nyelvet, amely lényeges bôvítéseket nyújt elôdjével, a C-vel
szemben. Objektumorientált nyelvként a C++ teljesen új
típusú programtervezést tesz lehetôvé. A dán kutató
Aarhusban tanult informatikát és matematikát, 1979-ben
doktorált informatikából Cambridge-ben. Fô kutatási
területei az osztott rendszerek, az operációs rendszerek, a
szimulációk, a programozási nyelvek és a programozás
módszertana. 1979 óta az AT&T Bell Laboratories Murry
Hillben (USA) lévô mûszaki kutatási központjában dolgozik.
@VIrodalom:@N
@VBjarne Stroustrup:@N The C++ Programming Language (A C++
programozási nyelv); Addison-Wesley 1986, 2.kiadás 1991.
@VTony Hansen:@N The C++ Answer Book (Válaszok a C++-szal
kapcsolatban); Addison-Wesley 1989.
@VStanley B. Lippman:@N C++ Einführung und Leitfaden
(Bevezetés a C++-ba); Addison-Wesley 1990.
@VStephen Dewhurst és Kathy Stark:@N Programming in C++
(Programozás C++-ban); Prentice-Hall, Englewood Cliffs, New
Jersey, 1989.
@VBruce Eckel:@N Using C++ (Munka a C++-szal); Osborne
McGraw-Hill 1989.